package com.itheima.app.manager;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.itheima.app.exception.PublishException;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.autoconfig.oss.OssTemplate;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.Comment;
import com.itheima.domain.mongo.Movement;
import com.itheima.domain.mongo.RecommendMovement;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.mongo.CommentService;
import com.itheima.service.mongo.MovementService;
import com.itheima.util.ConstantUtil;
import com.itheima.vo.CommentVo;
import com.itheima.vo.ErrorResult;
import com.itheima.vo.MovementVo;
import com.itheima.vo.PageBeanVo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.xml.ws.handler.PortInfo;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class MovementManager {


    @DubboReference
    private MovementService movementService;

    @DubboReference
    private CommentService commentService;

    @Autowired
    private OssTemplate ossTemplate;

    @DubboReference
    private UserInfoService userInfoService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private MQMovementManager mqMovementManager;



    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    //发布动态
    public ResponseEntity publishMovement(Movement movement, MultipartFile[] imageContent) throws IOException {

        //1.获取线程内的userid
        Long userId = UserHolder.get().getId();
        //判断是否被封禁
        if (stringRedisTemplate.hasKey("freeze_publish_" + userId)) {
            return ResponseEntity.status(500).body(ErrorResult.publishFreezeError());
        }
        //2.上传图片到oss
        //2-1声明地址数组，存储图片地址
        List<String> medias = new ArrayList<>();
        //遍历图片
        for (MultipartFile multipartFile : imageContent) {
            String url = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());

            medias.add(url);
        }
        //3.完善动态详情
        movement.setId(ObjectId.get());
        movement.setUserId(userId);
        movement.setMedias(medias);
        movement.setState(0);//todo 暂时写1 后期会用阿里云审核
        movement.setCreated(System.currentTimeMillis());
        movement.setSeeType(1);//目前探花1.0公开所有
        movementService.publishMovement(movement);

        //5发送mq消息
        rabbitTemplate.convertAndSend("tanhua.movement.state",movement.getId().toHexString());

        // 发送动态日志行为
        mqMovementManager.sendMovement(userId, movement.getId(), MQMovementManager.MOVEMENT_PUBLISH);

        return ResponseEntity.ok(null);

    }
    //查询个人动态
    public ResponseEntity findMyMovementByPage(Long userId, Integer pageNum, Integer pageSize) {

        PageBeanVo pageBeanVo = movementService.findMyMovementByPage(userId, pageNum, pageSize);

        //封装movementVo
        //2-1声明voList
        List<MovementVo> voList = new ArrayList<>();

        List<Movement> movements = (List<Movement>) pageBeanVo.getItems();

        if (CollectionUtil.isNotEmpty(movements)) {
            for (Movement movement : movements) {
                UserInfo userInfo = userInfoService.findById(movement.getUserId());
                MovementVo movementVo = new MovementVo();
                movementVo.setUserInfo(userInfo);
                movementVo.setMovement(movement);
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE,userId,movement.getId().toHexString()))) {
                    movementVo.setHasLiked(1);
                }

                voList.add(movementVo);
            }
        }

        pageBeanVo.setItems(voList);
        return ResponseEntity.ok(pageBeanVo);
    }
    //查询好友动态
    public ResponseEntity findFriendMovementByPage(Integer pageNum, Integer pageSize) {
        Long userId = UserHolder.get().getId();

        PageBeanVo pageBeanVo = movementService.findFriendMovementByPage(userId, pageNum, pageSize);

        List<MovementVo> voList = new ArrayList<>();

        List<Movement> movements = (List<Movement>) pageBeanVo.getItems();
        if (CollectionUtil.isNotEmpty(movements)) {

            for (Movement movement : movements) {
                UserInfo userInfo = userInfoService.findById(movement.getUserId());

                MovementVo movementVo = new MovementVo();
                movementVo.setUserInfo(userInfo);
                movementVo.setMovement(movement);
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE,userId,movement.getId().toHexString()))) {
                    movementVo.setHasLiked(1);
                }
                voList.add(movementVo);
            }
        }
        pageBeanVo.setItems(voList);
        return ResponseEntity.ok(pageBeanVo);
    }
    //查询推荐动态
    public ResponseEntity findRecommendMovementByPage(Integer pageNum, Integer pageSize) {

        Long userId = UserHolder.get().getId();

        PageBeanVo pageBeanVo = movementService.findRecommendMovementByPage(userId, pageNum, pageSize);

        List<Movement> movements = (List<Movement>) pageBeanVo.getItems();

        List<MovementVo> voList = new ArrayList<>();

        if (CollectionUtil.isNotEmpty(movements)) {
            for (Movement movement : movements) {
                UserInfo userInfo = userInfoService.findById(movement.getUserId());

                MovementVo movementVo = new MovementVo();

                movementVo.setUserInfo(userInfo);

                movementVo.setMovement(movement);
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE,userId,movement.getId().toHexString()))) {
                    movementVo.setHasLiked(1);
                }
                voList.add(movementVo);
            }
        }
        pageBeanVo.setItems(voList);

        return ResponseEntity.ok(pageBeanVo);
    }
    //动态点赞
    public ResponseEntity movementLike(String publishId) {
        Long userId = UserHolder.get().getId();
        Movement movement = movementService.findById(new ObjectId(publishId));
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());
        comment.setPublishId(movement.getId());
        comment.setCommentType(1);
        comment.setUserId(userId);
        comment.setPublishUserId(movement.getUserId());

        Integer count = commentService.saveComment(comment);

        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, userId, publishId), "1");

        //  发送动态日志行为

        mqMovementManager.sendMovement(userId,movement.getId(),MQMovementManager.MOVEMENT_LIKE);

        return ResponseEntity.ok(count);
    }
    //取消点赞
    public ResponseEntity movementDisLike(String publishId) {

        Long userId = UserHolder.get().getId();

        Integer likeCount = commentService.removeComment(new ObjectId(publishId), userId, 1);

        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, userId, publishId));

        //  发送动态日志行为
        mqMovementManager.sendMovement(userId,new ObjectId(publishId),MQMovementManager.MOVEMENT_DISLIKE);

        return ResponseEntity.ok(likeCount);
    }

    //喜欢
    public ResponseEntity movementLove(String publishId) {
        Long userId = UserHolder.get().getId();

        Movement movement = movementService.findById(new ObjectId(publishId));

        Comment comment = new Comment();
        comment.setUserId(userId);
        comment.setCreated(System.currentTimeMillis());
        comment.setPublishId(movement.getId());
        comment.setPublishUserId(movement.getUserId());
        comment.setCommentType(3);

        Integer count = commentService.saveComment(comment);

        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.MOVEMENT_LOVE, userId, publishId), "1");

        //  发送动态日志行为
        mqMovementManager.sendMovement(userId,new ObjectId(publishId),MQMovementManager.MOVEMENT_LOVE);

        return ResponseEntity.ok(count);
    }
    //取消喜欢
    public ResponseEntity movementUnLove(String publishId) {
        Long userId = UserHolder.get().getId();

        Integer count = commentService.removeComment(new ObjectId(publishId), userId, 3);
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.MOVEMENT_LOVE, userId, publishId));
        //  发送动态日志行为
        mqMovementManager.sendMovement(userId,new ObjectId(publishId),MQMovementManager.MOVEMENT_DISLOVE);

        return ResponseEntity.ok(count);
    }
    //查询单挑动态
    public ResponseEntity findMovementVoById(String publishId) {
        Long userId = UserHolder.get().getId();
        Movement movement = movementService.findById(new ObjectId(publishId));

        UserInfo userInfo = userInfoService.findById(movement.getUserId());

        MovementVo movementVo = new MovementVo();
        movementVo.setUserInfo(userInfo);
        movementVo.setMovement(movement);

        //  发送动态日志行为
        mqMovementManager.sendMovement(userId,new ObjectId(publishId),MQMovementManager.MOVEMENT_BROWSE);
        return ResponseEntity.ok(movementVo);
    }
    //查询动态评论
    public ResponseEntity findMovementCommentVo(String publishId, Integer pageNum, Integer pageSize) {

        PageBeanVo pageBeanVo = commentService.findCommentByPage(new ObjectId(publishId), 2, pageNum, pageSize);

        List<CommentVo> list = new ArrayList<>();

        List<Comment> comments = (List<Comment>) pageBeanVo.getItems();

        if (CollectionUtil.isNotEmpty(comments)) {
            for (Comment comment : comments) {

                UserInfo userInfo = userInfoService.findById(comment.getUserId());

                CommentVo vo = new CommentVo();
                vo.setId(comment.getId().toHexString());
                vo.setAvatar(userInfo.getAvatar());
                vo.setNickname(userInfo.getNickname());
                vo.setContent(comment.getContent());
                vo.setCreateDate(DateUtil.formatDateTime(new Date(comment.getCreated())));
                list.add(vo);
            }
        }

        pageBeanVo.setItems(list);
        return ResponseEntity.ok(pageBeanVo);
    }
    //发表评论
    public ResponseEntity movementComment(String publishId, String content) {
        Long userId = UserHolder.get().getId();

        //查询是否被封禁
        if (stringRedisTemplate.hasKey("freeze_comment_" + userId)) {
            return ResponseEntity.status(500).body(ErrorResult.commentFreezeError());
        }

        Movement movement = movementService.findById(new ObjectId(publishId));

        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());
        comment.setPublishId(movement.getId());
        comment.setCommentType(2);
        comment.setUserId(userId);
        comment.setPublishUserId(movement.getUserId());
        comment.setContent(content);
        Integer count = commentService.saveComment(comment);

        //  发送动态日志行为
        mqMovementManager.sendMovement(userId,new ObjectId(publishId),MQMovementManager.MOVEMENT_COMMENT);
        return ResponseEntity.ok(count);
    }
}
